#include "typecheck_visitor.h"




/*--------------------------------------------------------------------*/

Visitor *typecheck_newVisitor() {
	Visitor *visitor = (Visitor *) malloc(sizeof(Visitor));
	visitor->visitorFunction = visitFunctions;
	return visitor;
}

/*--------------------------------------------------------------------*/


void tchk_visit_program(Visitor *visitor, TreeNode *node) {

    printf("tchk: programa \n");
    tree_node_accept_children(node->children, visitor);
}

/*--------------------------------------------------------------------*/


void tchk_visit_cabecalho_programa(Visitor *visitor, TreeNode *node) {
	//node->children->symbol->decl_linenum = node->linenum;
	printf("tchk: cab_programa\n");
    tree_node_accept(node->children, visitor);
}

/*--------------------------------------------------------------------*/


void tchk_visit_identificador(Visitor *visitor, TreeNode *node) {

	printf("tchk: identificador \n");
	if (!symbol_isAdded(node->name)) {
		printf("Error. Simbolo Nao Declarado: %s\n", node->name);
		exit(-1);
	}
}


/*--------------------------------------------------------------------*/


void tchk_visit_numero_sem_sinal(Visitor *visitor, TreeNode *node) {
	printf("tchk: numero sem sinal \n");
}

/*--------------------------------------------------------------------*/


void tchk_visit_parte_declaracao_variavel(Visitor *visitor, TreeNode *node) {
	printf("tchk: parte dec var\n");
	tree_node_accept_children(node->children, visitor);
}

/*--------------------------------------------------------------------*/

void tchk_visit_declaracao_variavel(Visitor *visitor, TreeNode *node) {
	printf("tchk: decl var\n");
	tree_node_accept_children(node->children, visitor);
}

/*--------------------------------------------------------------------*/


void tchk_visit_instrucao_lista(Visitor *visitor, TreeNode *node) {
	printf("tchk: instrucao lista\n");
	tree_node_accept_children(node->children, visitor);
}

/*--------------------------------------------------------------------*/


void tchk_visit_instrucao_de_atribuicao(Visitor *visitor, TreeNode *node) {
	printf("tchk: instrucao atribuicao\n");
	TreeNode *lnode = node->children;
    TreeNode *rnode = lnode->sibling;

    tree_node_accept(lnode, visitor);
    tree_node_accept(rnode, visitor);

    if (symbol_getType(symbol_search(head, lnode->name)) != rnode->type) {
        printf("Error: Tipos incompativeis na atribuicao.\n");
        exit(-1);
    }
}


/*--------------------------------------------------------------------*/


void tchk_visit_expressao_simples(Visitor *visitor, TreeNode *node) {
	printf("tchk: exp simples\n");
	TreeNode *lnode = node->children;
    TreeNode *op = lnode->sibling;
    TreeNode *rnode = op->sibling;

    tree_node_accept(lnode, visitor);
    tree_node_accept(rnode, visitor);
	
	/*@Author Capu
	 * BUG: NAO ESTOU CONSEGUINDO PEGAR O TIPO DA EXPRESSAO SIMPLES
	 * QUANDO A EXPRESSAO TEM MAIS DE 2 FILHOS
	 * 
	if (symbol_sameTypeByName(head, lnode->name, rnode->name)) {
		node->type = lnode->type;
	}
	else {
		printf("Error: Tipos incompativeis na expressao.\n");
		exit(-1);
	}
	*/
}
